package org.dftproject.genesis.ui.figures;

import java.util.Iterator;

import org.eclipse.draw2d.ActionEvent;
import org.eclipse.draw2d.ActionListener;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FigureListener;
import org.eclipse.draw2d.FocusEvent;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;

public class ButtonFigure extends Figure {

	private final Button control;

	public ButtonFigure(final Composite parent, int style) {
		setOpaque(true);

		control = new Button(parent, style);
		control.addTraverseListener(new TraverseListener() {

			public void keyTraversed(final TraverseEvent e) {
				if (e.detail == SWT.TRAVERSE_TAB_NEXT || e.detail == SWT.TRAVERSE_TAB_PREVIOUS) {
					Display.getCurrent().asyncExec(new Runnable() {

						public void run() {
							requestFocus();
							parent.setFocus();
							parent.traverse(e.detail);
						}
					});
					e.doit = false;
				}
			}

		});
		control.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				for (@SuppressWarnings("unchecked") Iterator<ActionListener> it = getListeners(ActionListener.class); it.hasNext();)
					it.next().actionPerformed(new ActionEvent(ButtonFigure.this));
			}
			
		});

		setRequestFocusEnabled(true);
		setFocusTraversable(true);
		addFigureListener(new FigureListener() {

			public void figureMoved(IFigure source) {
				Rectangle clientArea = getClientArea();
				control.setBounds(clientArea.x, clientArea.y, clientArea.width, clientArea.height);
			}

		});
	}

	@Override
	public void handleFocusGained(FocusEvent event) {
		super.handleFocusGained(event);
		control.setFocus();
	}

	@Override
	public void paint(Graphics graphics) {
	}

	@Override
	public Dimension getPreferredSize(int wHint, int hHint) {
		Point size = control.computeSize(wHint, hHint);
		if (wHint > -1)
			size.x = Math.min(wHint, size.x);
		if (hHint > -1)
			size.y = Math.min(hHint, size.y);
		return new Dimension(size.x, size.y);
	}

	public Button getControl() {
		return control;
	}

	public String getText() {
		return control.getText();
	}

	public void setText(String text) {
		control.setText(text);
	}

	public void addActionListener(ActionListener listener) {
		addListener(ActionListener.class, listener);
	}
	
	public void removeActionListener(ActionListener listener) {
		removeListener(ActionListener.class, listener);
	}

}
